package cn.donting.jme.edit.context;

import com.jme3.system.*;

import java.util.logging.Level;

/**
 * fx 的JmeDesktopSystem
 * 用于创建InputLwjglOffscreenBuffer 生成 FxInput
 * @author donting
 */
public class JmeDesktopFXSystem extends JmeDesktopSystem {

    static {
        JmeSystem.setSystemDelegate(new JmeDesktopFXSystem());
    }
    public static void load() {

    }

    @Override
    public JmeContext newContext(AppSettings settings, JmeContext.Type contextType) {
        initialize(settings);
        JmeContext ctx;
        if (settings.getRenderer() == null
                || settings.getRenderer().equals("NULL")
                || contextType == JmeContext.Type.Headless) {
            ctx = new NullContext();
            ctx.setSettings(settings);
        } else if (settings.getRenderer().startsWith("LWJGL")) {
            ctx = newContextLwjgl(settings, contextType);
            ctx.setSettings(settings);
        } else if (settings.getRenderer().startsWith("JOGL")) {
            ctx = newContextJogl(settings, contextType);
            ctx.setSettings(settings);
        } else if (settings.getRenderer().startsWith("CUSTOM")) {
            ctx = newContextCustom(settings, contextType);
            ctx.setSettings(settings);
        } else {
            throw new UnsupportedOperationException(
                    "Unrecognizable renderer specified: "
                            + settings.getRenderer());
        }
        return ctx;
    }

    private JmeContext newContextLwjgl(AppSettings settings, JmeContext.Type type) {
        try {
            Class ctxClazz = null;
            switch (type) {
                case Canvas:
                    ctxClazz = Class.forName("com.jme3.system.lwjgl.LwjglCanvas");
                    break;
                case Display:
                    ctxClazz = Class.forName("com.jme3.system.lwjgl.LwjglDisplay");
                    break;
                case OffscreenSurface:
                    ctxClazz = Class.forName("cn.donting.jme.edit.context.InputLwjglOffscreenBuffer");
                    break;
                default:
                    throw new IllegalArgumentException("Unsupported context type " + type);
            }

            return (JmeContext) ctxClazz.newInstance();
        } catch (InstantiationException | IllegalAccessException ex) {
            logger.log(Level.SEVERE, "Failed to create context", ex);
        } catch (ClassNotFoundException ex) {
            logger.log(Level.SEVERE, "CRITICAL ERROR: Context class is missing!\n"
                    + "Make sure jme3_lwjgl-ogl is on the classpath.", ex);
        }
        return null;
    }

    private JmeContext newContextJogl(AppSettings settings, JmeContext.Type type) {
        try {
            Class ctxClazz = null;
            switch (type) {
                case Display:
                    ctxClazz = Class.forName("com.jme3.system.jogl.JoglNewtDisplay");
                    break;
                case Canvas:
                    ctxClazz = Class.forName("com.jme3.system.jogl.JoglNewtCanvas");
                    break;
                case OffscreenSurface:
                    ctxClazz = Class.forName("com.jme3.system.jogl.JoglOffscreenBuffer");
                    break;
                default:
                    throw new IllegalArgumentException("Unsupported context type " + type);
            }

            return (JmeContext) ctxClazz.newInstance();
        } catch (InstantiationException | IllegalAccessException ex) {
            logger.log(Level.SEVERE, "Failed to create context", ex);
        } catch (ClassNotFoundException ex) {
            logger.log(Level.SEVERE, "CRITICAL ERROR: Context class is missing!\n"
                    + "Make sure jme3-jogl is on the classpath.", ex);
        }

        return null;
    }

    private JmeContext newContextCustom(AppSettings settings, JmeContext.Type type) {
        try {
            String className = settings.getRenderer().substring("CUSTOM".length());

            Class ctxClazz = Class.forName(className);
            return (JmeContext) ctxClazz.newInstance();
        } catch (InstantiationException | IllegalAccessException ex) {
            logger.log(Level.SEVERE, "Failed to create context", ex);
        } catch (ClassNotFoundException ex) {
            logger.log(Level.SEVERE, "CRITICAL ERROR: Context class is missing!", ex);
        }

        return null;
    }

}
